package com.strato.annotation.base.v1_0_0.registry;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.strato.base.bean.v1_0_0.BeanUtil;

public class ClassDescriptor extends AbstractAnnotationDescriptor{

	private String className;
	
	private List<FieldDescriptor> fieldDescriptors=new ArrayList<FieldDescriptor>();
	
	private List<MethodDescriptor> methodDescriptors=new ArrayList<MethodDescriptor>();

	private BundleDescriptor bundleDescriptor;
	
	public BundleDescriptor getBundleDescriptor() {
		return bundleDescriptor;
	}

	public void setBundleDescriptor(BundleDescriptor bundleDescriptor) {
		this.bundleDescriptor = bundleDescriptor;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public List<FieldDescriptor> getFieldDescriptors() {
		return fieldDescriptors;
	}

	public void setFieldDescriptors(List<FieldDescriptor> fieldDescriptors) {
		this.fieldDescriptors = fieldDescriptors;
	}

	public List<MethodDescriptor> getMethodDescriptors() {
		return methodDescriptors;
	}

	public void setMethodDescriptors(List<MethodDescriptor> methodDescriptors) {
		this.methodDescriptors = methodDescriptors;
	}

	public void discover(Class<?> clazz) {
		setClassName(clazz.getName());
		setAnnotations(extractAnnotations(clazz.getAnnotations()));
		for(Field field:BeanUtil.getFields(clazz)){
			FieldDescriptor fieldDescriptor=new FieldDescriptor();
			fieldDescriptor.setClassDescriptor(this);
			fieldDescriptor.discover(field);
			getFieldDescriptors().add(fieldDescriptor);
		}
		for(Method method:BeanUtil.getMethods(clazz)){
			if(method.getDeclaringClass().equals(Object.class)){
				continue;
			}
			MethodDescriptor methodDescriptor=new MethodDescriptor();
			methodDescriptor.setClassDescriptor(this);
			methodDescriptor.discover(method);
			getMethodDescriptors().add(methodDescriptor);
		}
	}

	public List<MethodDescriptor> findMethodDescriptors(Class<?> annotationType) {
		List<MethodDescriptor> list=new ArrayList<MethodDescriptor>();
		for(MethodDescriptor md:getMethodDescriptors()){
			boolean found=false;
			for(Annotation a:md.getAnnotations()){
				if(a.annotationType().equals(annotationType)){
					found=true;
					break;
				}
			}
			if(found){
				list.add(md);
			}
		}
		return list;
	}

}
